﻿#define _CRT_SECURE_NO_WARNINGS 1

#include  "string.h"

#include <string>
using namespace std;
//
//
//void func1()
//{
//	string s("Hello world");
//	/*cout << s << endl;
//	s.push_back('x');
//	cout << s << endl;
//	s.append("xxx");
//	cout << s << endl;
//	s += "ssss";
//	cout << s << endl;*/
//	size_t index1 = s.find('l', 0);
//	if (index1 != -1)
//	{
//		cout << s.substr(index1) << endl;
//	}
//	size_t index2 = s.rfind('l', 0);
//	if (index2 != -1)
//	{
//		cout << s.substr(index2) << endl;
//	}
//
//}
//
//void SplitFilename(string s)
//{
//	size_t found = s.find_first_of("/\\");
//	cout << s.substr(0,found) << endl;
//	cout << s.substr(found) << endl;
//}
//
//void func2()
//{
//	string s1("D:\\code\\cpp-language");//转义字符" \\ ---> \"
//	string s2("root/code/test");
//	SplitFilename(s1);
//	SplitFilename(s2);
//
//}
//
void func3()
{

	string a = "hello world";//深拷贝
	string b = a;//c_str返回指向数组的指针const char*
	std::cout << a.c_str() << std::endl;
	std::cout << "&a:" << &a << std::endl;
	std::cout << "&b:" << &b << std::endl;
	std::cout << "a.c_str:" ;
	printf("%p\n", a.c_str());
	std::cout << "b.c_str:" ;
	printf("%p\n", b.c_str());
	if (a.c_str() == b.c_str()) //a.c_str()
	{

		std::cout << "true" << std::endl;

	}
	else 
		std::cout << "false" << std::endl;
}

void func4()
{
	string strText = "How are you?";

	string strSeparator = " ";

	string strResult;

	int size_pos = 0;

	int size_prev_pos = 0;

	while ((size_pos = strText.find_first_of(strSeparator, size_pos)) != string::npos)
		  // 3  7
	{

		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);

		cout << strResult << " ";//How are

		size_prev_pos = ++size_pos;

	}
	//       9               11
	if (size_prev_pos != strText.size())

	{

		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);

		cout << strResult << " ";//you?

	}

	cout << endl;

}

//给定两个字符串形式的非负整数 num1 和num2 ，计算它们的和并同样以字符串形式返回。
//
//你不能使用任何內建的用于处理大整数的库（比如 BigInteger）， 也不能直接将输入的字符串转换为整数形式。
class Solution {
public:
	//数字相加尾插+逆置
	string addStrings(string num1, string num2) {
		int end1 = num1.size() - 1;
		int end2 = num2.size() - 1;
		int next = 0;
		string s;
		while (end1 >= 0 || end2 >= 0)
		{
			int ret1 = 0;
			int ret2 = 0;
			if (end1 >= 0)
			{
				ret1 = num1[end1] - '0';
			}
			if (end2 >= 0)
			{
				ret2 = num2[end2] - '0';
			}
			s += (ret1 + ret2 + next) % 10 + '0';
			next = (ret1 + ret2 + next) / 10;
			--end1;
			--end2;
		}
		if (next == 1)
			s += 1 + '0';
		reverse(s.begin(), s.end());//迭代器
		return s;
	}
};

//如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后，短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
//
//字母和数字都属于字母数字字符。
//
//给你一个字符串 s，如果它是 回文串 ，返回 true ；否则，返回 false 。


class Solution {
public:
	bool isLetterOrNumber(char ch)
	{
		return (ch >= '0' && ch <= '9')
			|| (ch >= 'a' && ch <= 'z')
			|| (ch >= 'A' && ch <= 'Z');
	}
	bool isnoequal(char ch1, char ch2)
	{
		if (ch1 >= 'A' && ch1 <= 'Z')
			ch1 += 32;
		if (ch2 >= 'A' && ch2 <= 'Z')
			ch2 += 32;
		//通过将大小转成小写
		//不用将全部数都变成小写
		return ch1 != ch2;
	}
	bool isPalindrome(string s)
	{
		int left = 0;
		int right = s.size() - 1;
		while (left < right)
		{
			while (left < right && !isLetterOrNumber(s[left]))
			{
				++left;
			}
			while (left < right && !isLetterOrNumber(s[right]))
			{
				--right;
			}
			if (isnoequal(s[left], s[right]))
			{
				return false;
			}
			++left;
			--right;
		}
		return true;

	}
};


//给定一个字符串 s 和一个整数 k，从字符串开头算起，每计数至 2k 个字符，就反转这 2k 字符中的前 k 个字符。
//
//如果剩余字符少于 k 个，则将剩余字符全部反转。
//如果剩余字符小于 2k 但大于或等于 k 个，则反转前 k 个字符，其余字符保持原样



class Solution {
public:
	void str_reverse(string& s, int left, int right)
	{
		while (left < right)
		{
			swap(s[left], s[right]);
			++left;
			--right;
		}
	}
	string reverseStr(string s, int k)
	{
		string s1;
		int cur = 0;
		int prev = 0;
		while (cur <= s.size())
		{

			cur += 2 * k;
			if (cur > s.size())
			{

				if (prev - 1 + k <= s.size() - 1)
					str_reverse(s, prev, prev - 1 + k);
				else
					str_reverse(s, prev, s.size() - 1);
				return s;
			}
			str_reverse(s, prev, prev + k - 1);

			prev = cur;
		}
		return s;
	}
};


//给定一个字符串 s ，你需要反转字符串中每个单词的字符顺序，同时仍保留空格和单词的初始顺序。

class Solution {
public:

	void str_reverse(string& s, int left, int right)
	{
		while (left < right)
		{
			swap(s[left], s[right]);
			++left;
			--right;
		}
	}
	string reverseWords(string s)
	{
		int cur = 0;
		int prev = 0;
		int len = s.size();
		while (cur <= len)
		{
			while (cur <= len && s[cur] != ' ')
			{
				++cur;
			}
			if (cur <= len)
			{
				str_reverse(s, prev, cur - 1);
				prev = ++cur;
			}
		}
		str_reverse(s, prev, cur - 2);
		return s;
	}
};


//给定两个以字符串形式表示的非负整数 num1 和 num2，返回 num1 和 num2 的乘积，它们的乘积也表示为字符串形式。
//
//注意：不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

class Solution {
public:

	string addStrings(string num1, string num2) {
		int end1 = num1.size() - 1;
		int end2 = num2.size() - 1;
		int next = 0;
		string s;
		while (end1 >= 0 || end2 >= 0)
		{
			int ret1 = 0;
			int ret2 = 0;
			if (end1 >= 0)
			{
				ret1 = num1[end1] - '0';
			}
			if (end2 >= 0)
			{
				ret2 = num2[end2] - '0';
			}
			s += (ret1 + ret2 + next) % 10 + '0';
			next = (ret1 + ret2 + next) / 10;
			--end1;
			--end2;
		}
		if (next == 1)
			s += 1 + '0';
		reverse(s.begin(), s.end());//迭代器
		return s;
	}
	string multiply1(string& n, int count, string cout)
	{
		string s;
		int cur = n.size() - 1;
		int carry = 0;
		while (cur >= 0)
		{
			s += ((n[cur] - '0') * count + carry) % 10 + '0';//要注意'0'
			carry = ((n[cur] - '0') * count + carry) / 10;
			--cur;
		}
		while (carry)//防止有进位没算
		{
			s += carry % 10 + '0';
			carry /= 10;
		}
		reverse(s.begin(), s.end());
		s += cout;
		return s;
	}
	string multiply(string num1, string num2)
	{

		int end2 = num2.size() - 1;
		int ret = 0;
		string s("0");
		string s1("0");
		string carry;
		while (end2 >= 0)
		{
			string s1 = multiply1(num1, (num2[end2] - '0'), carry);
			//使用num2的每一位乘以num1
			s = addStrings(s1, s);
			//得到的s1和s相加
			carry += '0';
			//这里的进位不需要计算直接加到后面就行
			--end2;
		}
		if (s[0] == '0')
			return string("0");
		return s;
	}
};